package com.zlp.clazz;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * 泛型的理解：
 * 本质就是语法唐，参数化类型，使用的时候限定类型，提高程序的安全性
 * 编译成字节码的时候为了兼顾以前的二进制文件会进行泛型擦除，
 * 但是会在LocaVaribleTypeTable表中的Signture属性中保存了参数化的类型，可通过反射获取
 */
public class Parametric {

    static int a;

    /**
     * 被final修饰的静态变量，不会在字节码中进行复制编译的时候就已确定
     */
    final static int b = 10;

    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        Method aa = Parametric.class.getMethod("aa", List.class);
        Type[] types = aa.getGenericParameterTypes();
        for (Type type:types) {
            //如果不是参数类型，直接返回
            if (type instanceof ParameterizedType) {
                //先强转为参数类型
                ParameterizedType curType = (ParameterizedType) type;
                //获取原始类型
                Type rawType = curType.getRawType();
                System.out.println(rawType);
                //获取参数类型
                Type[] arguments = curType.getActualTypeArguments();
                for (Type t : arguments) {
                    System.out.println(t);
                    System.out.println(t.getTypeName());
                }
            }
        }
        //verify();
    }
    static List<Integer> list1;
    public int aa(List<Integer> list) throws NoSuchFieldException, NoSuchMethodException {


        //noinspection ResultOfMethodCallIgnored
        Field field = Parametric.class.getDeclaredField("list1");
        Type genericFieldType = field.getGenericType();

        if(genericFieldType instanceof ParameterizedType){
            ParameterizedType aType = (ParameterizedType) genericFieldType;
            Type[] fieldArgTypes = aType.getActualTypeArguments();
            for(Type fieldArgType : fieldArgTypes){
                Class fieldArgClass = (Class) fieldArgType;
                System.out.println("fieldArgClass = " + fieldArgClass);
            }
        }


        System.out.println(field.getGenericType());
        return 1;
    }
    public static long aa1(List<String> list){
        return 1;
    }


    public static void verify(){
        Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Integer d = 3;
        Integer e = 321;
        Integer f = 321;
        Long g = 3L;
        System.out.println(c == d);
        System.out.println(e == f);
        System.out.println(c == (a+b));
        System.out.println(c.equals(a+b));
        System.out.println(g == (a+b));
        System.out.println(g.equals(a+b));
    }
}
